package com.qf.controller;

import com.aliyun.oss.model.DataRedundancyType;
import com.aliyun.oss.model.SSEAlgorithm;
import com.qf.service.GoodsService;
import com.qf.service.OrderService;
import com.qf.service.ProductService;
import com.qf.service.UserService;
import com.qf.util.ResponseUtil;
import com.qf.vo.*;
import jdk.management.resource.internal.inst.UnixAsynchronousServerSocketChannelImplRMHooks;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import sun.rmi.log.LogInputStream;

import java.math.BigDecimal;
import java.util.*;

@RestController
@CrossOrigin("*")
@RequestMapping("/dashboard")
public class IndexController {

    private final static Integer DAYS_RANGE = 30;
    @Autowired
    private UserService userService;

    @Autowired
    private GoodsService goodsService;

    @Autowired
    private ProductService productService;

    @Autowired
    private OrderService orderService;

    /**
     *首页统计
     * @return
     */
    @RequestMapping("")
    public Object indexCount(){
        Integer userCount = userService.userCount();
        Integer goodsCount = goodsService.goodsCount();
        Integer productCount = productService.productCount();
        Integer orderCount = orderService.orderCount();

        Map<String,Integer> data = new HashMap<>();
        data.put("userTotal", userCount);
        data.put("goodsTotal", goodsCount);
        data.put("productTotal", productCount);
        data.put("orderTotal", orderCount);

        return ResponseUtil.ok(data);
    }

    /**
     * 首页图表统计
     * @return
     */
    @RequestMapping("/chart")
    public Object chart(){

        UserOrderCntVo userOrderCntVo = new UserOrderCntVo();

        //统计近期订单的增长量
        List<DayStatis> orderCnts = orderService.orderStatis(DAYS_RANGE);
        //统计近期用户的增长量
        List<DayStatis> userCnts = userService.recentCount(DAYS_RANGE);

        //合并订单增长量集合中的日期和用户增长量中的日期, 日期去重并排序
        String[] days = unionDayData(userCnts, orderCnts);

        //将日期放入返回的vo中
        userOrderCntVo.setDayData(days);
        userOrderCntVo.setUserCnt(fetchArrCnt(days,userCnts));
        userOrderCntVo.setOrderCnt(fetchArrCnt(days, orderCnts));

        //订单收款统计, 订单笔数和订单金额
        OrderAmtsVo orderAmtsVo = fetchOrderAmtsVo(orderCnts);

        //按照分类统计销售额和销售数量
        List<CategorySellAmts> categorySell = orderService.categorySellAmt();
        CategorySellVo categorySellVo = fetchCategorySell(categorySell);

        //按照接口文档封装返回的数据
        Map<String,Object> data = new HashMap<>();
        data.put("userOrderCnt", userOrderCntVo);
        data.put("orderAmts", orderAmtsVo);
        data.put("categorySell", categorySellVo);

        return ResponseUtil.ok(data);
    }

    /**
     * 合并获取到的日期并排序, 日期要去重
     * @param userCnts
     * @param orderCnts
     * @return
     */
    private String[] unionDayData(List<DayStatis> userCnts,List<DayStatis> orderCnts){
        Set<String> days = new HashSet<>();

        //将用户增长量集合中的日期放入set中
        if (userCnts != null){
            for (DayStatis userCnt : userCnts) {
                days.add(userCnt.getDayStr());
            }
        }

        //将订单增长量中的日期放入set中
        if (orderCnts != null){
            for (DayStatis orderCnt : orderCnts) {
                days.add(orderCnt.getDayStr());
            }
        }

        //日期排序
        List<String> list = new ArrayList<String>(days);
        //按照升序排序
        Collections.sort(list);

        return list.toArray(new String[0]);
    }

    /**
     * 根据日期, 获取用户或者订单的增长量数据, 如果不存在默认值为0
     * @param dayData   统计的日期数组
     * @param statisCnts 统计的具体数据
     * @return
     */
    private int[] fetchArrCnt(String[] dayData,List<DayStatis> statisCnts){
        //返回的数据长度等同于日期数组长度
        int[] arrayCnts = new int[dayData.length];

        //将需要转换的集合数据, 变成map数据类型
        Map<String,Integer> cntsMap = new HashMap<>();
        if (statisCnts != null){
            for (DayStatis statisCnt : statisCnts) {
                cntsMap.put(statisCnt.getDayStr(),statisCnt.getCnts());
            }
        }

        //遍历日期数组
        for (int i = 0; i < dayData.length; i++) {
            //从map中根据日期作为key, 获取value值, 值就是这个日期对应的统计数据
            int cnt = 0;
            if (cntsMap.get(dayData[i]) != null){
                cnt = cntsMap.get(dayData[i]);
            }
            //给统计的数组赋值, 也就是统计数据
            arrayCnts[i] = cnt;
        }
        return arrayCnts;
    }

    /**
     *统计订单按照天的增长量和金额
     * @param orderCnts
     * @return
     */
    private OrderAmtsVo fetchOrderAmtsVo(List<DayStatis> orderCnts){
        OrderAmtsVo vo = new OrderAmtsVo();

        //订单统计集合的长度
        int size = 0;
        if (orderCnts != null && orderCnts.size()>0){
            size = orderCnts.size();
        }

        //定义存放日期的数组
        String[] dayData = new String[size];
        //定义日订单金额数组
        BigDecimal[] orderAmtData = new BigDecimal[size];
        //定义日订单量数组
        int[] orderCntData = new int[size];

        for (int i = 0; i < size; i++) {
            dayData[i] = orderCnts.get(i).getDayStr();
            orderAmtData[i] = orderCnts.get(i).getAmts();
            orderCntData[i] = orderCnts.get(i).getCnts();
        }

        vo.setDayData(dayData);
        vo.setOrderAmtData(orderAmtData);
        vo.setOrderCntData(orderCntData);
        return vo;
    }

    /**
     * 合并统计一级类目对应的销售额
     * @param categorySell
     * @return
     */
    public CategorySellVo fetchCategorySell(List<CategorySellAmts> categorySell){
        CategorySellVo vo = new CategorySellVo();

        //集合长度
        int size = 0;
        if (categorySell != null && categorySell.size()>0){
            size = categorySell.size();
        }

        String[] categoryNames = new String[size];
        for (int i = 0; i < size; i++) {
            categoryNames[i] = categorySell.get(i).getName();
        }

        vo.setCategoryNames(categoryNames);
        vo.setCategorySellData(categorySell);
        return vo;
    }
}
